| Conditions | 1 |
| Paths | > 20000 |
| Total Lines | 457 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 1 | ||
| Bugs | 0 | Features | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
| 1 | /*! Copyright (c) 2011 Piotr Rochala (http://rocha.la) |
||
| 11 | slimScroll: function(options) { |
||
| 12 | |||
| 13 | var defaults = { |
||
| 14 | |||
| 15 | // width in pixels of the visible scroll area |
||
| 16 | width : 'auto', |
||
| 17 | |||
| 18 | // height in pixels of the visible scroll area |
||
| 19 | height : '250px', |
||
| 20 | |||
| 21 | // width in pixels of the scrollbar and rail |
||
| 22 | size : '7px', |
||
| 23 | |||
| 24 | // scrollbar color, accepts any hex/color value |
||
| 25 | color: '#000', |
||
| 26 | |||
| 27 | // scrollbar position - left/right |
||
| 28 | position : 'right', |
||
| 29 | |||
| 30 | // distance in pixels between the side edge and the scrollbar |
||
| 31 | distance : '1px', |
||
| 32 | |||
| 33 | // default scroll position on load - top / bottom / $('selector') |
||
| 34 | start : 'top', |
||
| 35 | |||
| 36 | // sets scrollbar opacity |
||
| 37 | opacity : .4, |
||
| 38 | |||
| 39 | // enables always-on mode for the scrollbar |
||
| 40 | alwaysVisible : false, |
||
| 41 | |||
| 42 | // check if we should hide the scrollbar when user is hovering over |
||
| 43 | disableFadeOut : false, |
||
| 44 | |||
| 45 | // sets visibility of the rail |
||
| 46 | railVisible : false, |
||
| 47 | |||
| 48 | // sets rail color |
||
| 49 | railColor : '#333', |
||
| 50 | |||
| 51 | // sets rail opacity |
||
| 52 | railOpacity : .2, |
||
| 53 | |||
| 54 | // whether we should use jQuery UI Draggable to enable bar dragging |
||
| 55 | railDraggable : true, |
||
| 56 | |||
| 57 | // defautlt CSS class of the slimscroll rail |
||
| 58 | railClass : 'slimScrollRail', |
||
| 59 | |||
| 60 | // defautlt CSS class of the slimscroll bar |
||
| 61 | barClass : 'slimScrollBar', |
||
| 62 | |||
| 63 | // defautlt CSS class of the slimscroll wrapper |
||
| 64 | wrapperClass : 'slimScrollDiv', |
||
| 65 | |||
| 66 | // check if mousewheel should scroll the window if we reach top/bottom |
||
| 67 | allowPageScroll : false, |
||
| 68 | |||
| 69 | // scroll amount applied to each mouse wheel step |
||
| 70 | wheelStep : 20, |
||
| 71 | |||
| 72 | // scroll amount applied when user is using gestures |
||
| 73 | touchScrollStep : 200, |
||
| 74 | |||
| 75 | // sets border radius |
||
| 76 | borderRadius: '7px', |
||
| 77 | |||
| 78 | // sets border radius of the rail |
||
| 79 | railBorderRadius : '7px' |
||
| 80 | }; |
||
| 81 | |||
| 82 | var o = $.extend(defaults, options); |
||
| 83 | |||
| 84 | // do it for every element that matches selector |
||
| 85 | this.each(function(){ |
||
| 86 | |||
| 87 | var isOverPanel, isOverBar, isDragg, queueHide, touchDif, |
||
| 88 | barHeight, percentScroll, lastScroll, |
||
| 89 | divS = '<div></div>', |
||
| 90 | minBarHeight = 30, |
||
| 91 | releaseScroll = false; |
||
| 92 | |||
| 93 | // used in event handlers and for better minification |
||
| 94 | var me = $(this); |
||
| 95 | |||
| 96 | // ensure we are not binding it again |
||
| 97 | if (me.parent().hasClass(o.wrapperClass)) |
||
| 98 | { |
||
| 99 | // start from last bar position |
||
| 100 | var offset = me.scrollTop(); |
||
| 101 | |||
| 102 | // find bar and rail |
||
| 103 | bar = me.siblings('.' + o.barClass); |
||
| 104 | rail = me.siblings('.' + o.railClass); |
||
| 105 | |||
| 106 | getBarHeight(); |
||
| 107 | |||
| 108 | // check if we should scroll existing instance |
||
| 109 | if ($.isPlainObject(options)) |
||
| 110 | { |
||
| 111 | // Pass height: auto to an existing slimscroll object to force a resize after contents have changed |
||
| 112 | if ( 'height' in options && options.height == 'auto' ) { |
||
| 113 | me.parent().css('height', 'auto'); |
||
| 114 | me.css('height', 'auto'); |
||
| 115 | var height = me.parent().parent().height(); |
||
| 116 | me.parent().css('height', height); |
||
| 117 | me.css('height', height); |
||
| 118 | } else if ('height' in options) { |
||
| 119 | var h = options.height; |
||
| 120 | me.parent().css('height', h); |
||
| 121 | me.css('height', h); |
||
| 122 | } |
||
| 123 | |||
| 124 | if ('scrollTo' in options) |
||
| 125 | { |
||
| 126 | // jump to a static point |
||
| 127 | offset = parseInt(o.scrollTo); |
||
| 128 | } |
||
| 129 | else if ('scrollBy' in options) |
||
| 130 | { |
||
| 131 | // jump by value pixels |
||
| 132 | offset += parseInt(o.scrollBy); |
||
| 133 | } |
||
| 134 | else if ('destroy' in options) |
||
| 135 | { |
||
| 136 | // remove slimscroll elements |
||
| 137 | bar.remove(); |
||
| 138 | rail.remove(); |
||
| 139 | me.unwrap(); |
||
| 140 | return; |
||
| 141 | } |
||
| 142 | |||
| 143 | // scroll content by the given offset |
||
| 144 | scrollContent(offset, false, true); |
||
| 145 | } |
||
| 146 | |||
| 147 | return; |
||
| 148 | } |
||
| 149 | else if ($.isPlainObject(options)) |
||
| 150 | { |
||
| 151 | if ('destroy' in options) |
||
| 152 | { |
||
| 153 | return; |
||
| 154 | } |
||
| 155 | } |
||
| 156 | |||
| 157 | // optionally set height to the parent's height |
||
| 158 | o.height = (o.height == 'auto') ? me.parent().height() : o.height; |
||
| 159 | |||
| 160 | // wrap content |
||
| 161 | var wrapper = $(divS) |
||
| 162 | .addClass(o.wrapperClass) |
||
| 163 | .css({ |
||
| 164 | position: 'relative', |
||
| 165 | overflow: 'hidden', |
||
| 166 | width: o.width, |
||
| 167 | height: o.height |
||
| 168 | }); |
||
| 169 | |||
| 170 | // update style for the div |
||
| 171 | me.css({ |
||
| 172 | overflow: 'hidden', |
||
| 173 | width: o.width, |
||
| 174 | height: o.height |
||
| 175 | }); |
||
| 176 | |||
| 177 | // create scrollbar rail |
||
| 178 | var rail = $(divS) |
||
| 179 | .addClass(o.railClass) |
||
| 180 | .css({ |
||
| 181 | width: o.size, |
||
| 182 | height: '100%', |
||
| 183 | position: 'absolute', |
||
| 184 | top: 0, |
||
| 185 | display: (o.alwaysVisible && o.railVisible) ? 'block' : 'none', |
||
| 186 | 'border-radius': o.railBorderRadius, |
||
| 187 | background: o.railColor, |
||
| 188 | opacity: o.railOpacity, |
||
| 189 | zIndex: 90 |
||
| 190 | }); |
||
| 191 | |||
| 192 | // create scrollbar |
||
| 193 | var bar = $(divS) |
||
| 194 | .addClass(o.barClass) |
||
| 195 | .css({ |
||
| 196 | background: o.color, |
||
| 197 | width: o.size, |
||
| 198 | position: 'absolute', |
||
| 199 | top: 0, |
||
| 200 | opacity: o.opacity, |
||
| 201 | display: o.alwaysVisible ? 'block' : 'none', |
||
| 202 | 'border-radius' : o.borderRadius, |
||
| 203 | BorderRadius: o.borderRadius, |
||
| 204 | MozBorderRadius: o.borderRadius, |
||
| 205 | WebkitBorderRadius: o.borderRadius, |
||
| 206 | zIndex: 99 |
||
| 207 | }); |
||
| 208 | |||
| 209 | // set position |
||
| 210 | var posCss = (o.position == 'right') ? { right: o.distance } : { left: o.distance }; |
||
| 211 | rail.css(posCss); |
||
| 212 | bar.css(posCss); |
||
| 213 | |||
| 214 | // wrap it |
||
| 215 | me.wrap(wrapper); |
||
| 216 | |||
| 217 | // append to parent div |
||
| 218 | me.parent().append(bar); |
||
| 219 | me.parent().append(rail); |
||
| 220 | |||
| 221 | // make it draggable and no longer dependent on the jqueryUI |
||
| 222 | if (o.railDraggable){ |
||
| 223 | bar.bind("mousedown", function(e) { |
||
| 224 | var $doc = $(document); |
||
| 225 | isDragg = true; |
||
| 226 | t = parseFloat(bar.css('top')); |
||
|
|
|||
| 227 | pageY = e.pageY; |
||
| 228 | |||
| 229 | $doc.bind("mousemove.slimscroll", function(e){ |
||
| 230 | currTop = t + e.pageY - pageY; |
||
| 231 | bar.css('top', currTop); |
||
| 232 | scrollContent(0, bar.position().top, false);// scroll content |
||
| 233 | }); |
||
| 234 | |||
| 235 | $doc.bind("mouseup.slimscroll", function(e) { |
||
| 236 | isDragg = false;hideBar(); |
||
| 237 | $doc.unbind('.slimscroll'); |
||
| 238 | }); |
||
| 239 | return false; |
||
| 240 | }).bind("selectstart.slimscroll", function(e){ |
||
| 241 | e.stopPropagation(); |
||
| 242 | e.preventDefault(); |
||
| 243 | return false; |
||
| 244 | }); |
||
| 245 | } |
||
| 246 | |||
| 247 | // on rail over |
||
| 248 | rail.hover(function(){ |
||
| 249 | showBar(); |
||
| 250 | }, function(){ |
||
| 251 | hideBar(); |
||
| 252 | }); |
||
| 253 | |||
| 254 | // on bar over |
||
| 255 | bar.hover(function(){ |
||
| 256 | isOverBar = true; |
||
| 257 | }, function(){ |
||
| 258 | isOverBar = false; |
||
| 259 | }); |
||
| 260 | |||
| 261 | // show on parent mouseover |
||
| 262 | me.hover(function(){ |
||
| 263 | isOverPanel = true; |
||
| 264 | showBar(); |
||
| 265 | hideBar(); |
||
| 266 | }, function(){ |
||
| 267 | isOverPanel = false; |
||
| 268 | hideBar(); |
||
| 269 | }); |
||
| 270 | |||
| 271 | // support for mobile |
||
| 272 | me.bind('touchstart', function(e,b){ |
||
| 273 | if (e.originalEvent.touches.length) |
||
| 274 | { |
||
| 275 | // record where touch started |
||
| 276 | touchDif = e.originalEvent.touches[0].pageY; |
||
| 277 | } |
||
| 278 | }); |
||
| 279 | |||
| 280 | me.bind('touchmove', function(e){ |
||
| 281 | // prevent scrolling the page if necessary |
||
| 282 | if(!releaseScroll) |
||
| 283 | { |
||
| 284 | e.originalEvent.preventDefault(); |
||
| 285 | } |
||
| 286 | if (e.originalEvent.touches.length) |
||
| 287 | { |
||
| 288 | // see how far user swiped |
||
| 289 | var diff = (touchDif - e.originalEvent.touches[0].pageY) / o.touchScrollStep; |
||
| 290 | // scroll content |
||
| 291 | scrollContent(diff, true); |
||
| 292 | touchDif = e.originalEvent.touches[0].pageY; |
||
| 293 | } |
||
| 294 | }); |
||
| 295 | |||
| 296 | // set up initial height |
||
| 297 | getBarHeight(); |
||
| 298 | |||
| 299 | // check start position |
||
| 300 | if (o.start === 'bottom') |
||
| 301 | { |
||
| 302 | // scroll content to bottom |
||
| 303 | bar.css({ top: me.outerHeight() - bar.outerHeight() }); |
||
| 304 | scrollContent(0, true); |
||
| 305 | } |
||
| 306 | else if (o.start !== 'top') |
||
| 307 | { |
||
| 308 | // assume jQuery selector |
||
| 309 | scrollContent($(o.start).position().top, null, true); |
||
| 310 | |||
| 311 | // make sure bar stays hidden |
||
| 312 | if (!o.alwaysVisible) { bar.hide(); } |
||
| 313 | } |
||
| 314 | |||
| 315 | // attach scroll events |
||
| 316 | attachWheel(this); |
||
| 317 | |||
| 318 | function _onWheel(e) |
||
| 319 | { |
||
| 320 | // use mouse wheel only when mouse is over |
||
| 321 | if (!isOverPanel) { return; } |
||
| 322 | |||
| 323 | var e = e || window.event; |
||
| 324 | |||
| 325 | var delta = 0; |
||
| 326 | if (e.wheelDelta) { delta = -e.wheelDelta/120; } |
||
| 327 | if (e.detail) { delta = e.detail / 3; } |
||
| 328 | |||
| 329 | var target = e.target || e.srcTarget || e.srcElement; |
||
| 330 | if ($(target).closest('.' + o.wrapperClass).is(me.parent())) { |
||
| 331 | // scroll content |
||
| 332 | scrollContent(delta, true); |
||
| 333 | } |
||
| 334 | |||
| 335 | // stop window scroll |
||
| 336 | if (e.preventDefault && !releaseScroll) { e.preventDefault(); } |
||
| 337 | if (!releaseScroll) { e.returnValue = false; } |
||
| 338 | } |
||
| 339 | |||
| 340 | function scrollContent(y, isWheel, isJump) |
||
| 341 | { |
||
| 342 | releaseScroll = false; |
||
| 343 | var delta = y; |
||
| 344 | var maxTop = me.outerHeight() - bar.outerHeight(); |
||
| 345 | |||
| 346 | if (isWheel) |
||
| 347 | { |
||
| 348 | // move bar with mouse wheel |
||
| 349 | delta = parseInt(bar.css('top')) + y * parseInt(o.wheelStep) / 100 * bar.outerHeight(); |
||
| 350 | |||
| 351 | // move bar, make sure it doesn't go out |
||
| 352 | delta = Math.min(Math.max(delta, 0), maxTop); |
||
| 353 | |||
| 354 | // if scrolling down, make sure a fractional change to the |
||
| 355 | // scroll position isn't rounded away when the scrollbar's CSS is set |
||
| 356 | // this flooring of delta would happened automatically when |
||
| 357 | // bar.css is set below, but we floor here for clarity |
||
| 358 | delta = (y > 0) ? Math.ceil(delta) : Math.floor(delta); |
||
| 359 | |||
| 360 | // scroll the scrollbar |
||
| 361 | bar.css({ top: delta + 'px' }); |
||
| 362 | } |
||
| 363 | |||
| 364 | // calculate actual scroll amount |
||
| 365 | percentScroll = parseInt(bar.css('top')) / (me.outerHeight() - bar.outerHeight()); |
||
| 366 | delta = percentScroll * (me[0].scrollHeight - me.outerHeight()); |
||
| 367 | |||
| 368 | if (isJump) |
||
| 369 | { |
||
| 370 | delta = y; |
||
| 371 | var offsetTop = delta / me[0].scrollHeight * me.outerHeight(); |
||
| 372 | offsetTop = Math.min(Math.max(offsetTop, 0), maxTop); |
||
| 373 | bar.css({ top: offsetTop + 'px' }); |
||
| 374 | } |
||
| 375 | |||
| 376 | // scroll content |
||
| 377 | me.scrollTop(delta); |
||
| 378 | |||
| 379 | // fire scrolling event |
||
| 380 | me.trigger('slimscrolling', ~~delta); |
||
| 381 | |||
| 382 | // ensure bar is visible |
||
| 383 | showBar(); |
||
| 384 | |||
| 385 | // trigger hide when scroll is stopped |
||
| 386 | hideBar(); |
||
| 387 | } |
||
| 388 | |||
| 389 | function attachWheel(target) |
||
| 390 | { |
||
| 391 | if (window.addEventListener) |
||
| 392 | { |
||
| 393 | target.addEventListener('DOMMouseScroll', _onWheel, false ); |
||
| 394 | target.addEventListener('mousewheel', _onWheel, false ); |
||
| 395 | } |
||
| 396 | else |
||
| 397 | { |
||
| 398 | document.attachEvent("onmousewheel", _onWheel) |
||
| 399 | } |
||
| 400 | } |
||
| 401 | |||
| 402 | function getBarHeight() |
||
| 403 | { |
||
| 404 | // calculate scrollbar height and make sure it is not too small |
||
| 405 | barHeight = Math.max((me.outerHeight() / me[0].scrollHeight) * me.outerHeight(), minBarHeight); |
||
| 406 | bar.css({ height: barHeight + 'px' }); |
||
| 407 | |||
| 408 | // hide scrollbar if content is not long enough |
||
| 409 | var display = barHeight == me.outerHeight() ? 'none' : 'block'; |
||
| 410 | bar.css({ display: display }); |
||
| 411 | } |
||
| 412 | |||
| 413 | function showBar() |
||
| 414 | { |
||
| 415 | // recalculate bar height |
||
| 416 | getBarHeight(); |
||
| 417 | clearTimeout(queueHide); |
||
| 418 | |||
| 419 | // when bar reached top or bottom |
||
| 420 | if (percentScroll == ~~percentScroll) |
||
| 421 | { |
||
| 422 | //release wheel |
||
| 423 | releaseScroll = o.allowPageScroll; |
||
| 424 | |||
| 425 | // publish approporiate event |
||
| 426 | if (lastScroll != percentScroll) |
||
| 427 | { |
||
| 428 | var msg = (~~percentScroll == 0) ? 'top' : 'bottom'; |
||
| 429 | me.trigger('slimscroll', msg); |
||
| 430 | } |
||
| 431 | } |
||
| 432 | else |
||
| 433 | { |
||
| 434 | releaseScroll = false; |
||
| 435 | } |
||
| 436 | lastScroll = percentScroll; |
||
| 437 | |||
| 438 | // show only when required |
||
| 439 | if(barHeight >= me.outerHeight()) { |
||
| 440 | //allow window scroll |
||
| 441 | releaseScroll = true; |
||
| 442 | return; |
||
| 443 | } |
||
| 444 | bar.stop(true,true).fadeIn('fast'); |
||
| 445 | if (o.railVisible) { rail.stop(true,true).fadeIn('fast'); } |
||
| 446 | } |
||
| 447 | |||
| 448 | function hideBar() |
||
| 449 | { |
||
| 450 | // only hide when options allow it |
||
| 451 | if (!o.alwaysVisible) |
||
| 452 | { |
||
| 453 | queueHide = setTimeout(function(){ |
||
| 454 | if (!(o.disableFadeOut && isOverPanel) && !isOverBar && !isDragg) |
||
| 455 | { |
||
| 456 | bar.fadeOut('slow'); |
||
| 457 | rail.fadeOut('slow'); |
||
| 458 | } |
||
| 459 | }, 1000); |
||
| 460 | } |
||
| 461 | } |
||
| 462 | |||
| 463 | }); |
||
| 464 | |||
| 465 | // maintain chainability |
||
| 466 | return this; |
||
| 467 | } |
||
| 468 | }); |
||
| 475 |